import { GameObject } from "./GameObject";
import { Cell } from "./Cell";

export class Snake extends GameObject {
    constructor(info, gamemap) {
        super()

        this.id = info.id;
        this.color = info.color;
        this.gamemap = gamemap;
        this.cells = [new Cell(info.r, info.c)];

        this.speed = 5;//蛇每秒移动几格
        this.drection = -1;//指令情况 -1(无)，0（w），1（d），2(s)，3(a)
        this.status = "stop"; //stop 静止 move 移动  die 死亡

        this.next_target = null; //下一步去哪里

        //偏移量
        this.dr = [-1, 0, 1, 0];//行
        this.dc = [0, 1, 0, -1];//列

        //回合数
        this.step = 0;

        //误差
        this.eps = 1e-1;

        this.eye_direction = 0;
        if (this.id === 1) this.eye_direction = 2;//左下角朝上 右上角朝上

        this.eye_dx = [
            [-1, 1],
            [1, 1],
            [1, -1],
            [-1, -1]
        ]

        this.eye_dy = [
            [-1, -1],
            [-1, 1],
            [1, 1],
            [1, -1]
        ]

    }

    start() {

    }

    //读取用户输入指令
    set_derection(d) {
        this.drection = d;
    }

    //走下一步
    next_step() {
        const d = this.drection;
        this.next_target = new Cell(this.cells[0].r + this.dr[d], this.cells[0].c + this.dc[d]);
        this.eye_direction = d;
        this.drection = -1;//清空指令
        this.status = "move";//状态改变
        this.step++;//回合数++

        const k = this.cells.length;

        for (let i = k; i > 0; i--) {
            this.cells[i] = JSON.parse(JSON.stringify(this.cells[i - 1]));
        }



    }

    //移动
    update_move() {
        const dx = this.next_target.x - this.cells[0].x;
        const dy = this.next_target.y - this.cells[0].y;

        const d = Math.sqrt(dx * dx + dy * dy)

        if (d < this.eps) {
            this.cells[0] = JSON.parse(JSON.stringify(this.next_target));
            this.next_target = null;
            this.status = "stop";//走完了

            if (!this.check_length_add()) { //蛇不变砍掉尾巴
                this.cells.pop();
            }

        } else {
            const move_d = this.speed * this.timedelta / 1000;
            this.cells[0].x += move_d * (dx / d);
            this.cells[0].y += move_d * (dy / d);

            //过场动画
            if (!this.check_length_add()) {
                const k = this.cells.length;
                const tail = this.cells[k - 1], tail_target = this.cells[k - 2];
                const tail_dx = tail_target.x - tail.x;
                const tail_dy = tail_target.y - tail.y;
                tail.x += move_d * tail_dx / d;
                tail.y += move_d * tail_dy / d;
            }
        }
    }

    //检查当前回合 蛇的长度是否增加
    check_length_add() {
        if (this.step <= 10) {
            //增加
            return true;
        } else {
            //每三回合增加一次
            if ((this.step - 10) % 3 === 0) {
                return true;
            }
        }
        return false;
    }

    update() {
        if (this.status === "move") this.update_move()
        this.render()
    }

    render() {
        const L = this.gamemap.L;
        const ctx = this.gamemap.ctx;

        ctx.fillStyle = this.color;
        if (this.status === "die") ctx.fillStyle = "white";
        for (const cell of this.cells) {
            ctx.beginPath();
            ctx.arc(cell.x * L, cell.y * L, L / 2 * 0.8, 0, Math.PI * 2);
            ctx.fill()
        }


        for (let i = 1; i < this.cells.length; i++) {
            const a = this.cells[i - 1], b = this.cells[i];

            if (Math.abs(a.x - b.x) < this.exp && Math.abs(a.y - b.y) < this.exp) continue
            if (Math.abs(a.x - b.x) < this.eps) {
                ctx.fillRect((a.x - 0.4) * L, Math.min(a.y, b.y) * L, L * 0.8, Math.abs(a.y - b.y) * L)
            } else {
                ctx.fillRect(Math.min(a.x, b.x) * L, (a.y - 0.4) * L, Math.abs(a.x - b.x) * L, L * 0.8)
            }
        }


        ctx.fillStyle = "black";
        for (let i = 0; i < 2; i++) {
            const eye_x = (this.cells[0].x + this.eye_dx[this.eye_direction][i] * 0.15) * L;
            const eye_y = (this.cells[0].y + this.eye_dy[this.eye_direction][i] * 0.15) * L;

            ctx.beginPath();
            ctx.arc(eye_x, eye_y, L * 0.05, 0, Math.PI * 2);
            ctx.fill();

        }
    }


}